#include "VendingMachine.h"
#include <iostream>

VendingMachine::VendingMachine( Printer &prt, NameServer &nameServer, 
        						unsigned int id, unsigned int sodaCost,
								unsigned int maxStockPerFlavour ): 
myPrinter(prt), myNameServer(nameServer), myID(id),
mySodaCost(sodaCost), myMaxStockPerFlavour(maxStockPerFlavour)
{
	// initialize the stock of each flavour to 0
	myInventory = new unsigned int[FLAVOUR_SIZE];			
	for(int i=0; i<FLAVOUR_SIZE; i++)
	{
		myInventory[i] = 0;
	}

	// register ourself with the NameServer
	myNameServer.VMregister(this);
}

VendingMachine::~VendingMachine()
{
	delete[] myInventory;
}

void VendingMachine::main()
{
	myPrinter.print(Printer::Vending, myID, 'S', mySodaCost); 
	while(true)
	{
		// other than the destructor,
		// only calls to Buy and inventory are possible
		_Accept(~VendingMachine)
		{
			break;
		}
		or _Accept(buy)
		{
			// nothign to be done after buy
		}
		or _Accept(inventory)
		{
			// If inventory is called, then we do not accpt Buy
			// until retocked is called.
			// Since we only have one truck, we cannot have another
			// inventory before a restocked call.

			// We don't have to open door for destructor here.
			// VM can only be deleted after truck is dead, so
			// this will definitely execute before VM should be
			// destoryed.
			_Accept(restocked);
			myPrinter.print(Printer::Vending, myID, 'R');
		} // the _Accepts 
	} // while(true)

	myPrinter.print(Printer::Vending, myID, 'F');
}

VendingMachine::Status 
VendingMachine::buy( Flavours flavour, WATCard &card )
{
	// if the that flavour is out of stock ...
	if(myInventory[flavour] <= 0) return VendingMachine::STOCK;
	if(card.getBalance() < mySodaCost) return VendingMachine::FUNDS;

	card.withdraw(mySodaCost);
	myInventory[flavour] -= 1;
	myPrinter.print(Printer::Vending, myID, 'B', 
					(int)flavour, myInventory[flavour]);

    return VendingMachine::BUY;
}

unsigned int *VendingMachine::inventory()
{
	myPrinter.print(Printer::Vending, myID, 'r');
    return myInventory;
}

void VendingMachine::restocked()
{
}

_Nomutex unsigned int VendingMachine::cost()
{

    return mySodaCost;
}

_Nomutex unsigned int VendingMachine::getId()
{

    return myID;
}
